package terminal.network;

import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.ArrayList;
import java.util.Random;
import terminal.utility.DataUpdater;
import terminal.utility.Symbol;

public class Network extends Thread {

    private MulticastSocket socket;
    private InetAddress group;
    private ArrayList<Symbol> symbolList;
    private String curRev;
    private final int PORT = 3500;

    public Network() {
        try {
            group = InetAddress.getByName("224.2.2.2");
            socket = new MulticastSocket(PORT);
            socket.joinGroup(group);
        } catch (Exception e) {
            System.err.println("Network: " + e.toString());
        }
    }

    public void send(String data) {
        try {
            byte[] buf = data.getBytes("UTF-8");
            DatagramPacket dtg = new DatagramPacket(buf, buf.length, group, PORT);
            socket.send(dtg);
        } catch (Exception e) {
            System.err.println("Send Failed: " + e.toString());
        }
    }

    public void run() {
        while (true) {
            try {
                byte[] buf = new byte[5120];
                DatagramPacket rev = new DatagramPacket(buf, 0, buf.length, group, PORT);
                socket.receive(rev);

                String data = new String(buf, 0, rev.getLength());

                if (isDesired(data)) {
                    int loc = 0;
                    for (int i = 0; i < symbolList.size(); i++) {
                        if (symbolList.get(i).getSymText().equals(curRev)) {
                            loc = i;
                            break;
                        }
                    }
                    int dots = (new Random().nextInt(4)) + 1;
                    String status = "receiving data";

                    switch (dots) {
                        case 1:
                            status += ".";
                            break;
                        case 2:
                            status += "..";
                            break;
                        case 3:
                            status += "...";
                            break;
                        case 4:
                            status += "....";
                            break;
                        case 5:
                            status += ".....";
                            break;
                    }
                    if (data.contains("35=W")) {
                        System.out.println(curRev + " W");
                        DataUpdater.getInstance().updateStatus(loc, status);
                        DataUpdater.getInstance().updateAll(loc, data);
                        //System.out.println(data.replace("\r", "|"));
                    } else if (data.contains("35=X")) {
                        System.out.println(curRev + " X");
                        DataUpdater.getInstance().updateStatus(loc, status);
                        DataUpdater.getInstance().updateSome(loc, data);
                        //System.out.println(data.replace("\r", "|"));
                    } else if (data.contains("35=V")) {
                        DataUpdater.getInstance().updateStatus(loc, "requesting '" + curRev + "'...");
                        System.out.println(curRev);
                    } else if (data.contains("35=Y")) {
                        DataUpdater.getInstance().updateStatus(loc, "there is no such a symbol");
                        System.out.println(curRev);
                    }
                }
                System.out.println(data.replace("\r", " | "));
                System.gc();
            } catch (Exception e) {
                //System.err.println("Receive Failed: " + e.toString());
            }
        }

    }

    public void setReqSymbols(ArrayList<Symbol> symbolList) {
        this.symbolList = symbolList;
    }

    public void disconnect() {
        try {
            socket.close();
        } catch (Exception e) {
            System.err.println("Disconnect Failed: " + e.toString());
        }
    }

    private boolean isDesired(String data) {
        boolean isReq = false;
        for (Symbol y : symbolList) {
            if (data.contains(y.getSymText())) {
                isReq = true;
                curRev = y.getSymText();
                break;
            }
        }
        return isReq;
    }
}